/**
 * Project Name:SM Maven Webapp
 * File Name:ControllerAspect.java
 * Package Name:cn.sh.ideal.mir.session.aspect
 * Date:2015年1月22日上午10:05:32
 * Copyright (c) 2015, 上海理想信息产业（集团） All Rights Reserved.
 *
*/

package cn.sh.ideal.log.controller.aspect;

import java.lang.reflect.Method;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;





















import cn.sh.ideal.log.controller.annotation.MethodName;
import cn.sh.ideal.log.controller.model.ControllerLog;
import cn.sh.ideal.log.controller.service.ControllerLogService;
import cn.sh.ideal.log.controller.util.IpUtil;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;

/**
 * ClassName:ControllerAspect <br/>
 * Function: 拦截所有@requestMapping方法，也就是controller的方法
 * Reason:	 将方法的名称、传递的参数。返回值，调用的ip等等信息记录到数据库或日志中
 * Date:     2015年1月22日 上午10:05:32 <br/>
 * @author   GengHongChuang
 * @version  
 * @since    JDK 1.6  //@Aspect
//@Component
 * @see 	 
 */
@Aspect
@Component
public class ControllerAspect {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    
    @Autowired
    private ControllerLogService controllerLogService;
 

    @AfterReturning(value = "@annotation(org.springframework.web.bind.annotation.RequestMapping)", argNames = "returnValue", returning = "returnValue")
    public void afterInsertMethod(JoinPoint joinPoint, Object returnValue) {
        
        try {
            Signature signature = joinPoint.getSignature();

          /*  if (signature.getDeclaringTypeName().equals("sy.controller.aop.ControllerLogController")) {// 这个类的方法不需要记录日志
                return;
            }*/

            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            // HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();

            ControllerLog controllerLog = new ControllerLog();
            controllerLog.setIp(IpUtil.getIp(request));// 哪个IP访问的方法

            // System.out.println("类型：" + signature.getDeclaringType());
            // System.out.println("类型名" + signature.getDeclaringTypeName());
            controllerLog.setClassName(signature.getDeclaringTypeName());

            // System.out.println("修改器：" + signature.getModifiers());
            // System.out.println("方法名称:" + signature.getName());
            controllerLog.setMethodName(signature.getName());
            // System.out.println("方法全名：" + signature.toLongString());
            controllerLog.setMethodFullname(signature.toLongString());
            // System.out.println("方法短名：" + signature.toShortString());

            MethodSignature methodSignature = (MethodSignature) signature;
            Method method = methodSignature.getMethod();
            MethodName methodNameAnnotation = method.getAnnotation(MethodName.class);
            if (methodNameAnnotation != null) {
                // System.out.println("中文方法名：" + methodNameAnnotation.name());
                controllerLog.setMethodChname(methodNameAnnotation.name());
                controllerLog.setModuleName(methodNameAnnotation.moduleName());
            } else {
                controllerLog.setMethodChname("方法上并没有添加@MethodName(name = '中文方法名')的注解");
            }

            List<Object> argsList = new ArrayList<Object>();

            for (int i = 0; i < joinPoint.getArgs().length; i++) {
                Object arg = joinPoint.getArgs()[i];
                if (null != arg) {
                    // String argClassName = arg.getClass().getSimpleName();
                    if (arg instanceof HttpServletResponse) {
                        argsList.add("HttpServletResponse");
                    } else if (arg instanceof HttpServletRequest) {
                        argsList.add("HttpServletRequest");
                    } else if (arg instanceof HttpSession) {
                        argsList.add("HttpSession");
                    } else {
                        argsList.add(arg);
                    }
                }
            }

            // System.out.println("参数：" + JSON.toJSONString(argsList, filter, SerializerFeature.WriteDateUseDateFormat, SerializerFeature.DisableCircularReferenceDetect));
            controllerLog.setArgsContent(JSON.toJSONString(argsList,  SerializerFeature.WriteDateUseDateFormat, SerializerFeature.DisableCircularReferenceDetect));

            // System.out.println("返回值：" + JSON.toJSONString(returnValue, filter, SerializerFeature.WriteDateUseDateFormat, SerializerFeature.DisableCircularReferenceDetect));
            controllerLog.setReturnValue(JSON.toJSONString(returnValue,  SerializerFeature.WriteDateUseDateFormat, SerializerFeature.DisableCircularReferenceDetect));
            
      // System.out.println(controllerLog.toString());
            InetAddress addr = InetAddress.getLocalHost();
            String hostIp=addr.getHostAddress().toString(); //获取本机ip  
            String hostName=addr.getHostName().toString(); //获取本机计算机名称  
            String username = null;
            controllerLog.setHostIp(hostIp);
            controllerLog.setComputerName(hostName);
            controllerLog.setUsername(username);
            
            
            controllerLogService.log(controllerLog);
        } catch (Exception e) {
            logger.error("记录用户请求日志报错：", e);
            
        }
       
    }
   
}
